//*****************************************************************************
//**************** (C) 2008 by Eleven Engineering Incorporated ****************
//*****************************************************************************
//**
//**		Tabs:	This file looks best with tab stops set every 6 spaces.
//**
//*****************************************************************************
//*****************************************************************************
//**
//** File:		Thread0_Code.asm
//** Project:	Simple Sample Project for WHAM4
//** Revised:
//**
//** Description:	Code for Thread0
//**
//**
//**
//**
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------
// Setup the stack pointer for thread0
		mov   r7,T0_SP

//---------------------------------------------------
// Configure all of the I/O cells using the configuration table found at
// IOCbase in data memory.  This table contains configuration data required by
// the system as well as the application.  Before modifying the data in the
// table, ensure that you understand what configurations are needed by the
// system by referring to the XInC2 Users Guide.
//
	IOCellConfig:
		mov	r0,0
	IOCellConfig10:
		outp	r0,SCXioCfgP
		ld	r1,r0,IOCbase
		bc	ZC,IOCellConfig20
		mov	r1,0b1000011
	IOCellConfig20:
		outp	r1,SCXioCfgD
		add	r0,r0,1
		sub	r1,r0,IOClen
		bc	NE,IOCellConfig10


//-----------------------------------------------
// The next section configures the intenral PLL for 49.152Mhz
//assuming the external crystal frequency is 12.288Mhz
//After the PLL is running the system clock is switched from
//the crystal to the PLL

//Here we set up for the PLL and enable PLL, but not yet
//change the clock source to PLL
 // set output divider to 2
		mov	r0, 0x0001
		outp	r0, SCXPLLCfg1

// Configure Pll so the frequency output is 49.152 MHz for the XInC2
//Set FB to 16 i.e. and REF to 2 hence 8x12.288/2
//      mov	r0, 0x0805 //dont touch this, bad bad bad.
		mov	r0, 0x0407
		outp	r0, SCXPLLCfg0

//we still have to switch to RC first then to PLL
		inp	r0, SCXclkCfg
   		bic	r0, r0, 10        // choose rc
   		outp	r0, SCXclkCfg
  	WaitForRC:
   		inp	r0, SCXclkCfg
   		bc    NS, WaitForRC

// When clock switch occurs bit 15 of SCXclkCfg is set
		inp	r0, SCXclkCfg
   		bis	r0, r0, 11        // choose PLL
   		outp	r0, SCXclkCfg    // switch the mux
   		bis	r0, r0, 10        // run from PLL
   		outp    r0, SCXclkCfg
  	WaitForPLL:
   		inp	r0, SCXclkCfg
   		bc	NC, WaitForPLL
//2 instructions times at 32 kHz should give the PLL time to lock
//we are now running from PLL

//Configure BBU for low drive strength
		mov	r0,26
		outp	r0,SCXioCfgP
		mov	r0,0
		outp	r0,SCXioCfgD

//power up internal XInC2 ADC (takes ~1ms to stabilize)
//		mov	r0,ADC_powerUp
//		outp	r0,ADCcfg0

//configure the default interface to CC2400
		mov	r0,(1<<_CC2400_CSn | 1<<_CC2400_RX | 1<<_CC2400_TX) << 8 | (1<<_CC2400_CSn)
		ior	r0,r0,0xF300
		bis	r0,r0,7
		bis	r0,r0,5
		bis	r0,r0,4
		outp	r0,GPEcfg

		mov	r0,(1<<_BBUdirection)<<8
		outp	r0,GPHcfg

//SCX Crystal source, oscillator's output is enabled


		mov	r0,0b0000000110000011
		outp	r0,SCXaltCfg


//setup SPI0 for SPI-UART communication
		mov	r0,0b0000000000011011
		outp	r0,SPI0cfg				//setup the SPI_UART interface for slow SCK

		mov	r0,0b0000000000001111		//SCK = system/8
		outp	r0,SPI1cfg

		mov	r0,300<<8
		outp	r0,BBU0cfg1

		mov	r0,0b0001000001100011
		outp	r0,BBU0cfg0

//		mov	r0,12287
		outp	r0,BBU0brg					//setup baud rate

		mov	r0,0x217B
		outp	r0,BBU0start


//-----------------------------------------------

//configure Port C for LEDs, TURNED THIS OFF.
	//	mov	r0,0x0303
	//	outp	r0,GPCcfg

		//ECHO TEST
//		mov	r1,MSG_NEWLINE
//		jsr	r6,XPD_EchoString		//send a Carriage return / line feed
//		mov	r1,r0
//		jsr	r6,XPD_EchoHex		//send a Carriage return / line feed


//power up reset of CC2400
		mov	r1,0x00
		mov	r2,0x0000
		jsr	r6,put_CC2400_register

		mov	r1,0x00
		mov	r2,0x8000
		jsr	r6,put_CC2400_register


//-----------------------------------------------
//program the initial state of all the registers
		jsr	r6,put_CC2400_state


//-----------------------------------------------
//enable 16 MHz crystal on CC2400
		mov	r1,_SXOSCON_regAddr
		jsr	r6,put_CC2400_Strobe
	CC2400_OSC_turnon:
		mov	r1,_MAIN_regAddr
		jsr	r6,get_CC2400_status
		bic	r1,r1,6
		bc	VC,CC2400_OSC_turnon

//RESET ADC
//		mov	r0,0b1000000
//		outp	r0,ADCcfg1			//reset adc
//		rol	r0,r0,0
//		rol	r0,r0,0
//		rol	r0,r0,0
//		rol	r0,r0,0
//		rol	r0,r0,0
//		mov	r0,0b0000000
//		outp	r0,ADCcfg1			//release reset


//-----------------------------------------------
// Initialize SCUstop_status to current state of SCUstop register
// Use the SCUstop_status variable along with semaphores if multiple threads are changing the SCUstop register
// This is needed because SCUstop register in not readable.
		mov	r0, 0b11111110
		st	r0, SCUstop_status

// Echo the firmware version to the XPD port
		mov	r1,0x4000
		jsr	r6,XPD_ShiftInOut	//get current configuration
		and	r1,r1,0x3FFF
		sub	r1,r1,0x0001
		bc	NE,XPD_NotConnected
		mov	r1, VersionString
		jsr	r6, XPD_EchoString

	XPD_NotConnected:


//==============================================================
//Initialize Timer A for a 1 second Timer
//		mov	r0, 0x007A
////we are choosing 12000 Hz timing clock and count up not enabling the timer yet
//		outp	r0,TMRAcfg
//
//		mov	r0, 3000  //0.25 second timer
//		outp	r0, TMRACCR0
//
//		mov	r0, 0x0002
//		outp	r0, TMRACCM0cfg
////TimerA in compare mode


//-----------------------------------------------------------------
//Initialize Timer B for Varactor control on WHAM2rx module
//-----------------------------------------------------------------
	// Start the PWM to control the crystal frequency using the varactor
		mov	r0,0x007F
		outp	r0,TMRBCCM1cfg	// Timer 1 compare mode, input disabled, output enabled, reset/set operation

		mov	r0,_PWM_Period
		outp 	r0,TMRBCCR0	// Set the number of steps to count	to _PWM_Period

		mov	r0,190
		outp	r0,TMRBCCR1	// Start PWM with duty cycle value that sets the Rx freq. close to the Tx. freq.

		mov	r0,0x000B		// Syatem Clock / 4
		outp	r0,TMRBcfg		// Enable timer 1 in up mode

//-----------------------------------------------
// WE HAVE NOW CONFIGURED ALL OF THE I/O INTO A DEFAULT STATE.

//-----------------------------------------------
//-----------------------------------------------
//Description of the example code
//The example code can be run on WHAM4 Alpha modules (RX and TX main baords)
//
//The following describes the basic function of each thread:
//Thread0: turned off after initial configuration
//Thread1: handles and displays 16bit counter displayed as ascii hex to a PC running a terminal program (slave only)
//Thread2: not used
//Thread3: not used
//Thread4: not used
//Thread5: not used
//Thread6: RFlink_Manager
//Thread7: not used

//The interaction of threads 1,2 is described below:
//Threads 1&2 interact with each other through two shared variables
//Thread6 on the master generates a 16bit counter and updates the counter in a shared variable and sets a flag in another variable
//Thread1 on the slave waits for the flag to be set and then reads the updated Result value from the shared variable received from the master.
//When Thread1 finishes reading the Result and transfering it to the PC it will clear the shared flag

//The system is all configured now so startup the main program

#ifndef	_master

//-----------------------------------------------
//setup state for thread1
//set r7 = stack pointer
//set program counter = Enter_Thread1
		mov	r3,1<<_SCU_semaphore
		outp	r3,SCUdown

		mov   r0,T1_SP
		mov   r1,Enter_Thread1
		mov   r2,_Thread1<<3 | 7
		outp  r2,SCUpntr
		outp  r1,SCUpc					//set Program counter
		outp	r0,SCUreg					//set Stack Pointer

//Start Thread1

		ld	r2,SCUstop_status
		bic	r2,r2,_Thread1
		st	r2,SCUstop_status
		outp	r2,SCUstop

		outp	r3,SCUup
#endif


//setup state for thread6
//set r7 = stack pointer
//set program counter = Enter_Thread6
		//mov   r0,T6_SP
		//mov   r1,Enter_Thread6
		//mov   r2,_Thread6<<3 | 7
		//outp  r2,SCUpntr
		//outp  r1,SCUpc					//set Program counter
		//outp	r0,SCUreg					//set Stack Pointer

//Start Thread6

		//ld	r2,SCUstop_status
		//bic	r2,r2,_Thread6
		//st	r2,SCUstop_status
		//outp	r2,SCUstop

		//outp	r3,SCUup


	bra	@		//breakboint just in case a the thread is restarted


